import type { Context } from 'elysia';
import { verifyToken, extractTokenFromHeader, isTokenExpiringSoon } from '../utils/jwt';
import type { JWTPayload } from '../utils/jwt';

export interface AuthContext extends Context {
  user?: JWTPayload;
}

/**
 * 认证中间件 - 验证JWT令牌
 */
export function authMiddleware() {
  return (app: any) => app.derive(async (context: Context) => {
    const { headers, set } = context;
    const authHeader = headers.authorization;
    const token = extractTokenFromHeader(authHeader);
    
    if (!token) {
      console.warn('Authentication failed: No token provided');
      set.status = 401;
      return new Response(JSON.stringify({ error: '未提供认证令牌' }), {
        status: 401,
        headers: { 'Content-Type': 'application/json' }
      });
    }
    
    const payload = verifyToken(token);
    if (!payload) {
      console.warn('Authentication failed: Invalid token');
      set.status = 401;
      return new Response(JSON.stringify({ error: '无效的认证令牌' }), {
        status: 401,
        headers: { 'Content-Type': 'application/json' }
      });
    }
    
    // 检查令牌是否即将过期
    const expiringSoon = isTokenExpiringSoon(token);
    
    // console.log(`User authenticated: ${payload.username} (${payload.role})${expiringSoon ? ' - Token expiring soon' : ''}`);
    
    // 将用户信息添加到上下文中
    return { 
      user: payload,
      tokenExpiringSoon: expiringSoon
    };
  });
}

/**
 * 可选认证中间件 - 如果有令牌则验证，没有则跳过
 */
export function optionalAuthMiddleware() {
  return (app: any) => app.derive(async (context: Context) => {
    const { headers } = context;
    const authHeader = headers.authorization;
    const token = extractTokenFromHeader(authHeader);
    
    if (!token) {
      return { user: null };
    }
    
    const payload = verifyToken(token);
    return { user: payload };
  });
}

/**
 * 管理员权限中间件
 */
export function adminMiddleware() {
  return (app: any) => app.derive(async (context: Context) => {
    const { headers, set } = context;
    const authHeader = headers.authorization;
    const token = extractTokenFromHeader(authHeader);
    
    if (!token) {
      console.warn('Admin access denied: No token provided');
      set.status = 401;
      return new Response(JSON.stringify({ error: '未提供认证令牌' }), {
        status: 401,
        headers: { 'Content-Type': 'application/json' }
      });
    }
    
    const payload = verifyToken(token);
    if (!payload) {
      console.warn('Admin access denied: Invalid token');
      set.status = 401;
      return new Response(JSON.stringify({ error: '无效的认证令牌' }), {
        status: 401,
        headers: { 'Content-Type': 'application/json' }
      });
    }
    
    if (payload.role !== 'admin') {
      console.warn(`Admin access denied: User ${payload.username} has insufficient permissions (role: ${payload.role})`);
      set.status = 403;
      return new Response(JSON.stringify({ error: '权限不足，需要管理员权限' }), {
        status: 403,
        headers: { 'Content-Type': 'application/json' }
      });
    }
    
    // console.log(`Admin access granted: ${payload.username}`);
    return { user: payload };
  });
}

/**
 * 游客可访问中间件 - 允许游客查看但不能编辑
 */
export function guestAccessMiddleware() {
  return (app: any) => app.derive(async (context: Context) => {
    const { headers } = context;
    const authHeader = headers.authorization;
    const token = extractTokenFromHeader(authHeader);
    
    // 如果没有token，允许游客访问
    if (!token) {
      return { user: null };
    }
    
    const payload = verifyToken(token);
    if (!payload) {
      // 如果token无效，仍然允许游客访问
      return { user: null };
    }
    
    // 允许所有有效角色访问，包括admin和guest
    // 不需要限制角色类型，因为这是游客可访问的中间件
    
    // console.log(`Access granted: ${payload.username} (${payload.role})`);
    return { user: payload };
  });
}

/**
 * 只读权限检查函数
 */
export function checkReadOnlyAccess(userRole: string, method: string): boolean {
  // 游客只能进行GET操作
  if (userRole === 'guest' && method !== 'GET') {
    return false;
  }
  return true;
}

// 兼容性导出
export const authenticateToken = authMiddleware;